{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a81e2dde",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>code</th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>preclose</th>\n",
       "      <th>volume</th>\n",
       "      <th>amount</th>\n",
       "      <th>adjustflag</th>\n",
       "      <th>turn</th>\n",
       "      <th>tradestatus</th>\n",
       "      <th>pctChg</th>\n",
       "      <th>isST</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2022-07-07</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.03</td>\n",
       "      <td>4.09</td>\n",
       "      <td>4.03</td>\n",
       "      <td>4.06</td>\n",
       "      <td>4.04</td>\n",
       "      <td>8635967</td>\n",
       "      <td>3.512546e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>0.5881</td>\n",
       "      <td>1</td>\n",
       "      <td>0.4950</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-08</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.08</td>\n",
       "      <td>4.11</td>\n",
       "      <td>4.07</td>\n",
       "      <td>4.09</td>\n",
       "      <td>4.06</td>\n",
       "      <td>8339713</td>\n",
       "      <td>3.412329e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>0.5680</td>\n",
       "      <td>1</td>\n",
       "      <td>0.7389</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-11</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.07</td>\n",
       "      <td>4.08</td>\n",
       "      <td>4.04</td>\n",
       "      <td>4.07</td>\n",
       "      <td>4.09</td>\n",
       "      <td>10530338</td>\n",
       "      <td>4.270048e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>0.7171</td>\n",
       "      <td>1</td>\n",
       "      <td>-0.4890</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-12</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.06</td>\n",
       "      <td>4.13</td>\n",
       "      <td>4.05</td>\n",
       "      <td>4.06</td>\n",
       "      <td>4.07</td>\n",
       "      <td>12442692</td>\n",
       "      <td>5.092482e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>0.8474</td>\n",
       "      <td>1</td>\n",
       "      <td>-0.2457</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-13</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.08</td>\n",
       "      <td>4.12</td>\n",
       "      <td>4.07</td>\n",
       "      <td>4.10</td>\n",
       "      <td>4.06</td>\n",
       "      <td>9415447</td>\n",
       "      <td>3.858624e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>0.6412</td>\n",
       "      <td>1</td>\n",
       "      <td>0.9852</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-14</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.11</td>\n",
       "      <td>4.17</td>\n",
       "      <td>4.08</td>\n",
       "      <td>4.12</td>\n",
       "      <td>4.10</td>\n",
       "      <td>15791688</td>\n",
       "      <td>6.521171e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>1.0754</td>\n",
       "      <td>1</td>\n",
       "      <td>0.4878</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-15</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.11</td>\n",
       "      <td>4.12</td>\n",
       "      <td>4.02</td>\n",
       "      <td>4.03</td>\n",
       "      <td>4.12</td>\n",
       "      <td>15427031</td>\n",
       "      <td>6.275451e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>1.0506</td>\n",
       "      <td>1</td>\n",
       "      <td>-2.1845</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-18</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.04</td>\n",
       "      <td>4.11</td>\n",
       "      <td>4.01</td>\n",
       "      <td>4.10</td>\n",
       "      <td>4.03</td>\n",
       "      <td>10306828</td>\n",
       "      <td>4.206106e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>0.7019</td>\n",
       "      <td>1</td>\n",
       "      <td>1.7370</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-19</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.12</td>\n",
       "      <td>4.13</td>\n",
       "      <td>4.08</td>\n",
       "      <td>4.11</td>\n",
       "      <td>4.10</td>\n",
       "      <td>10430707</td>\n",
       "      <td>4.275436e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>0.7104</td>\n",
       "      <td>1</td>\n",
       "      <td>0.2439</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-20</th>\n",
       "      <td>sh.688425</td>\n",
       "      <td>4.15</td>\n",
       "      <td>4.27</td>\n",
       "      <td>4.15</td>\n",
       "      <td>4.22</td>\n",
       "      <td>4.11</td>\n",
       "      <td>35524394</td>\n",
       "      <td>1.496170e+08</td>\n",
       "      <td>2</td>\n",
       "      <td>2.4193</td>\n",
       "      <td>1</td>\n",
       "      <td>2.6764</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 code  open  high   low  close  preclose    volume  \\\n",
       "date                                                                 \n",
       "2022-07-07  sh.688425  4.03  4.09  4.03   4.06      4.04   8635967   \n",
       "2022-07-08  sh.688425  4.08  4.11  4.07   4.09      4.06   8339713   \n",
       "2022-07-11  sh.688425  4.07  4.08  4.04   4.07      4.09  10530338   \n",
       "2022-07-12  sh.688425  4.06  4.13  4.05   4.06      4.07  12442692   \n",
       "2022-07-13  sh.688425  4.08  4.12  4.07   4.10      4.06   9415447   \n",
       "2022-07-14  sh.688425  4.11  4.17  4.08   4.12      4.10  15791688   \n",
       "2022-07-15  sh.688425  4.11  4.12  4.02   4.03      4.12  15427031   \n",
       "2022-07-18  sh.688425  4.04  4.11  4.01   4.10      4.03  10306828   \n",
       "2022-07-19  sh.688425  4.12  4.13  4.08   4.11      4.10  10430707   \n",
       "2022-07-20  sh.688425  4.15  4.27  4.15   4.22      4.11  35524394   \n",
       "\n",
       "                  amount  adjustflag    turn  tradestatus  pctChg  isST  \n",
       "date                                                                     \n",
       "2022-07-07  3.512546e+07           2  0.5881            1  0.4950     0  \n",
       "2022-07-08  3.412329e+07           2  0.5680            1  0.7389     0  \n",
       "2022-07-11  4.270048e+07           2  0.7171            1 -0.4890     0  \n",
       "2022-07-12  5.092482e+07           2  0.8474            1 -0.2457     0  \n",
       "2022-07-13  3.858624e+07           2  0.6412            1  0.9852     0  \n",
       "2022-07-14  6.521171e+07           2  1.0754            1  0.4878     0  \n",
       "2022-07-15  6.275451e+07           2  1.0506            1 -2.1845     0  \n",
       "2022-07-18  4.206106e+07           2  0.7019            1  1.7370     0  \n",
       "2022-07-19  4.275436e+07           2  0.7104            1  0.2439     0  \n",
       "2022-07-20  1.496170e+08           2  2.4193            1  2.6764     0  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from localdata import anyone\n",
    "\n",
    "data = anyone()\n",
    "data[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f8068105",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "daf4e7af",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'sh.688425'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "7d6bc967",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'铁建重工'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9a7ec247",
   "metadata": {},
   "outputs": [],
   "source": [
    "data, code, name = anyone()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "03e2a1fe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>code</th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>preclose</th>\n",
       "      <th>volume</th>\n",
       "      <th>amount</th>\n",
       "      <th>adjustflag</th>\n",
       "      <th>turn</th>\n",
       "      <th>tradestatus</th>\n",
       "      <th>pctChg</th>\n",
       "      <th>isST</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2022-07-07</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>5.93</td>\n",
       "      <td>5.96</td>\n",
       "      <td>5.82</td>\n",
       "      <td>5.85</td>\n",
       "      <td>5.91</td>\n",
       "      <td>10499466</td>\n",
       "      <td>6.172937e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>1.9694</td>\n",
       "      <td>1</td>\n",
       "      <td>-1.0152</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-08</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>5.81</td>\n",
       "      <td>5.86</td>\n",
       "      <td>5.68</td>\n",
       "      <td>5.82</td>\n",
       "      <td>5.85</td>\n",
       "      <td>14688740</td>\n",
       "      <td>8.501505e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>2.7552</td>\n",
       "      <td>1</td>\n",
       "      <td>-0.5128</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-11</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>5.81</td>\n",
       "      <td>5.81</td>\n",
       "      <td>5.70</td>\n",
       "      <td>5.78</td>\n",
       "      <td>5.82</td>\n",
       "      <td>9388758</td>\n",
       "      <td>5.393830e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>1.7611</td>\n",
       "      <td>1</td>\n",
       "      <td>-0.6873</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-12</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>5.85</td>\n",
       "      <td>5.85</td>\n",
       "      <td>5.64</td>\n",
       "      <td>5.66</td>\n",
       "      <td>5.78</td>\n",
       "      <td>13079760</td>\n",
       "      <td>7.474993e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>2.4534</td>\n",
       "      <td>1</td>\n",
       "      <td>-2.0761</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-13</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>5.66</td>\n",
       "      <td>5.71</td>\n",
       "      <td>5.60</td>\n",
       "      <td>5.67</td>\n",
       "      <td>5.66</td>\n",
       "      <td>8801300</td>\n",
       "      <td>4.980473e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>1.6509</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1767</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-14</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>5.62</td>\n",
       "      <td>5.85</td>\n",
       "      <td>5.59</td>\n",
       "      <td>5.82</td>\n",
       "      <td>5.67</td>\n",
       "      <td>12105363</td>\n",
       "      <td>6.954247e+07</td>\n",
       "      <td>2</td>\n",
       "      <td>2.2706</td>\n",
       "      <td>1</td>\n",
       "      <td>2.6455</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-15</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>5.91</td>\n",
       "      <td>6.28</td>\n",
       "      <td>5.70</td>\n",
       "      <td>6.13</td>\n",
       "      <td>5.82</td>\n",
       "      <td>35797660</td>\n",
       "      <td>2.177923e+08</td>\n",
       "      <td>2</td>\n",
       "      <td>6.7147</td>\n",
       "      <td>1</td>\n",
       "      <td>5.3265</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-18</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>6.13</td>\n",
       "      <td>6.25</td>\n",
       "      <td>6.09</td>\n",
       "      <td>6.14</td>\n",
       "      <td>6.13</td>\n",
       "      <td>21983781</td>\n",
       "      <td>1.356671e+08</td>\n",
       "      <td>2</td>\n",
       "      <td>4.1236</td>\n",
       "      <td>1</td>\n",
       "      <td>0.1631</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-19</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>6.14</td>\n",
       "      <td>6.51</td>\n",
       "      <td>6.10</td>\n",
       "      <td>6.42</td>\n",
       "      <td>6.14</td>\n",
       "      <td>30698480</td>\n",
       "      <td>1.947638e+08</td>\n",
       "      <td>2</td>\n",
       "      <td>5.7582</td>\n",
       "      <td>1</td>\n",
       "      <td>4.5603</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-07-20</th>\n",
       "      <td>sz.002329</td>\n",
       "      <td>6.47</td>\n",
       "      <td>6.52</td>\n",
       "      <td>6.37</td>\n",
       "      <td>6.49</td>\n",
       "      <td>6.42</td>\n",
       "      <td>16998183</td>\n",
       "      <td>1.096462e+08</td>\n",
       "      <td>2</td>\n",
       "      <td>3.1884</td>\n",
       "      <td>1</td>\n",
       "      <td>1.0903</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 code  open  high   low  close  preclose    volume  \\\n",
       "date                                                                 \n",
       "2022-07-07  sz.002329  5.93  5.96  5.82   5.85      5.91  10499466   \n",
       "2022-07-08  sz.002329  5.81  5.86  5.68   5.82      5.85  14688740   \n",
       "2022-07-11  sz.002329  5.81  5.81  5.70   5.78      5.82   9388758   \n",
       "2022-07-12  sz.002329  5.85  5.85  5.64   5.66      5.78  13079760   \n",
       "2022-07-13  sz.002329  5.66  5.71  5.60   5.67      5.66   8801300   \n",
       "2022-07-14  sz.002329  5.62  5.85  5.59   5.82      5.67  12105363   \n",
       "2022-07-15  sz.002329  5.91  6.28  5.70   6.13      5.82  35797660   \n",
       "2022-07-18  sz.002329  6.13  6.25  6.09   6.14      6.13  21983781   \n",
       "2022-07-19  sz.002329  6.14  6.51  6.10   6.42      6.14  30698480   \n",
       "2022-07-20  sz.002329  6.47  6.52  6.37   6.49      6.42  16998183   \n",
       "\n",
       "                  amount  adjustflag    turn  tradestatus  pctChg  isST  \n",
       "date                                                                     \n",
       "2022-07-07  6.172937e+07           2  1.9694            1 -1.0152     0  \n",
       "2022-07-08  8.501505e+07           2  2.7552            1 -0.5128     0  \n",
       "2022-07-11  5.393830e+07           2  1.7611            1 -0.6873     0  \n",
       "2022-07-12  7.474993e+07           2  2.4534            1 -2.0761     0  \n",
       "2022-07-13  4.980473e+07           2  1.6509            1  0.1767     0  \n",
       "2022-07-14  6.954247e+07           2  2.2706            1  2.6455     0  \n",
       "2022-07-15  2.177923e+08           2  6.7147            1  5.3265     0  \n",
       "2022-07-18  1.356671e+08           2  4.1236            1  0.1631     0  \n",
       "2022-07-19  1.947638e+08           2  5.7582            1  4.5603     0  \n",
       "2022-07-20  1.096462e+08           2  3.1884            1  1.0903     0  "
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "fe3917ed",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'sz.002329'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e832ebc0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function localdata.anyone(frequency='day', klen=10)>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "anyone"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "26814a13",
   "metadata": {},
   "outputs": [],
   "source": [
    "import localdata"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "315ab0a8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<module 'localdata' from '/usr/local/lib/python3.8/dist-packages/localdata.py'>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "localdata"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "3abcf50f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#! /usr/bin/python\r\n",
      "# -*- coding: utf-8 -*-\r\n",
      "# @author HanYZ\r\n",
      "# @createAt 2022.07.17\r\n",
      "\r\n",
      "from os.path import expanduser, dirname, exists, getmtime, join\r\n",
      "from dateutil.relativedelta import relativedelta\r\n",
      "from datetime import datetime as dt\r\n",
      "from random import randint\r\n",
      "from os import makedirs\r\n",
      "import argparse\r\n",
      "import baostock as bs\r\n",
      "import pandas as pd\r\n",
      "import sys\r\n",
      "\r\n",
      "_datadir = join(expanduser('~'), '.local', 'datas')\r\n",
      "_sharedatadir = '/usr/local/share/datas' if sys.platform == 'linux' else _datadir\r\n",
      "\r\n",
      "_config = dict(\r\n",
      "    day = dict(\r\n",
      "        fields = \"date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,isST\",\r\n",
      "        filepath = lambda code: join(_datadir, 'day', code[:6], code+'.csv'),\r\n",
      "        sharefilepath = lambda code: join(_sharedatadir, 'day', code[:6], code+'.csv'),\r\n",
      "        listpath = join(_datadir, 'day', 'all_stock.csv'),\r\n",
      "        frequency = 'd',\r\n",
      "    ),\r\n",
      "    week = dict(\r\n",
      "        fields = \"date,code,open,high,low,close,volume,amount,adjustflag,turn,pctChg\",\r\n",
      "        filepath = lambda code: join(_datadir, 'week', code[:6], code+'.csv'),\r\n",
      "        sharefilepath = lambda code: join(_sharedatadir, 'week', code[:6], code+'.csv'),\r\n",
      "        listpath = join(_datadir, 'week', 'all_stock.csv'),\r\n",
      "        frequency = 'w',\r\n",
      "    )\r\n",
      ")\r\n",
      "\r\n",
      "def _lastDay(conf):\r\n",
      "    now = dt.now()\r\n",
      "    ld = now + relativedelta(hour=17, minute=35)\r\n",
      "    if ld > now:\r\n",
      "        ld += relativedelta(days=-1)\r\n",
      "    if ld.weekday() > 4 :\r\n",
      "        ld += relativedelta(days=4-ld.weekday())\r\n",
      "    elif ld.weekday() < 4 and conf['frequency'] == 'w':\r\n",
      "        ld += relativedelta(days=-3-ld.weekday())\r\n",
      "    return ld\r\n",
      "\r\n",
      "def _read_csv(filepath, klen):\r\n",
      "    data = pd.read_csv(filepath, index_col='date', parse_dates=True)\r\n",
      "    if klen > 0:\r\n",
      "        data = data.tail(klen)\r\n",
      "    return data\r\n",
      "\r\n",
      "def _to_csv(dataframe, filepath):\r\n",
      "    d = dirname(filepath)\r\n",
      "    if not exists(d):\r\n",
      "        makedirs(d)\r\n",
      "        print('创建', d)\r\n",
      "    dataframe.to_csv(filepath, index=0)\r\n",
      "\r\n",
      "def _downloadOne(code, conf, start_date='1991-01-01', write=True):\r\n",
      "    end_date = dt.now().date().isoformat()\r\n",
      "    rs = bs.query_history_k_data_plus(code, conf['fields'], start_date=start_date, end_date=end_date,\r\n",
      "                                      frequency=conf['frequency'], adjustflag='2').get_data()\r\n",
      "\r\n",
      "    # 写入文件\r\n",
      "    if len(rs) > 0:\r\n",
      "        write and _to_csv(rs, conf['filepath'](code))\r\n",
      "    else:\r\n",
      "        print('%s 的数据未读到' % code)\r\n",
      "    return rs\r\n",
      "\r\n",
      "def _refresh(code, conf, login=True):\r\n",
      "    filepath = conf['filepath'](code)\r\n",
      "    sharefilepath = conf['sharefilepath'](code)\r\n",
      "\r\n",
      "    if exists(sharefilepath) and dt.fromtimestamp(getmtime(sharefilepath)) > _lastDay(conf):  # 共享数据是新的\r\n",
      "        return False\r\n",
      "\r\n",
      "    if exists(filepath):  # 数据文件存在\r\n",
      "        if dt.fromtimestamp(getmtime(filepath)) > _lastDay(conf):  # 数据是新的\r\n",
      "            return False\r\n",
      "        if login:\r\n",
      "            bs.login()\r\n",
      "        old = _read_csv(filepath, klen=3)\r\n",
      "        if len(old) == 3:\r\n",
      "            last = old.index[0]\r\n",
      "            rs = _downloadOne(code, conf, start_date=last.date().isoformat(), write=False)\r\n",
      "            if len(rs) > 2 and old.open[2] == rs['open'].astype(float)[2]:  # 没有复权等情况影响历史数据\r\n",
      "                rs.loc[3:, :].to_csv(filepath, mode='a', index=False, header=None)\r\n",
      "                if login:\r\n",
      "                    bs.logout()\r\n",
      "                return True\r\n",
      "    elif login:\r\n",
      "        bs.login()\r\n",
      "\r\n",
      "    _downloadOne(code, conf)  # 重新下载\r\n",
      "    bs.logout\r\n",
      "    return True\r\n",
      "\r\n",
      "def _kdata(code, klen, conf, download=False):\r\n",
      "    filepath = conf['filepath'](code)\r\n",
      "    sharefilepath = conf['sharefilepath'](code)\r\n",
      "    if not exists(sharefilepath) and not exists(filepath):\r\n",
      "        download = True\r\n",
      "    download and _refresh(code, conf, True)\r\n",
      "    if exists(sharefilepath):\r\n",
      "        if exists(filepath) and getmtime(filepath) >= getmtime(sharefilepath):\r\n",
      "            return _read_csv(filepath, klen)\r\n",
      "        else:\r\n",
      "            return _read_csv(sharefilepath, klen)\r\n",
      "    else:\r\n",
      "        return _read_csv(filepath, klen)\r\n",
      "\r\n",
      "def _download(conf):\r\n",
      "    bs.login()\r\n",
      "    all_stock = bs.query_all_stock(_lastDay(conf).date().isoformat()).get_data()\r\n",
      "\r\n",
      "    cs = all_stock[~(all_stock.code.str.startswith('bj') | (all_stock.tradeStatus == '0') |\r\n",
      "                     all_stock.code_name.str.contains('退') | all_stock.code_name.str.contains('ST'))]\r\n",
      "    _to_csv(cs, conf['listpath'])\r\n",
      "\r\n",
      "    for i in cs.index:\r\n",
      "        c = cs.loc[i]\r\n",
      "        _refresh(cs.loc[i].code, conf, login=False)\r\n",
      "\r\n",
      "    bs.logout()\r\n",
      "    pass\r\n",
      "\r\n",
      "def _all_stock(conf):\r\n",
      "    filepath = conf['listpath']\r\n",
      "    if not exists(filepath):\r\n",
      "        _download(conf)\r\n",
      "    return pd.read_csv(filepath)\r\n",
      "\r\n",
      "def daily(code, klen=0, download=False):\r\n",
      "    return _kdata(code, klen, _config['day'], download)\r\n",
      "\r\n",
      "def weekly(code, klen=0, download=False):\r\n",
      "    return _kdata(code, klen, _config['week'], download)\r\n",
      "\r\n",
      "def anyone(frequency='day', klen=10):\r\n",
      "    '''任选一只证券，返回(Kdata, code, name)'''\r\n",
      "    conf = _config[frequency]\r\n",
      "    al = _all_stock(conf)\r\n",
      "    while True:\r\n",
      "        c = al.iloc[randint(0,len(al))]\r\n",
      "        d = _kdata(c.code, klen, conf, False)\r\n",
      "        if klen < 1 or len(d) >= klen:\r\n",
      "            return d, c.code, c.code_name\r\n",
      "\r\n",
      "def onebyone(frequency='day', klen=10, types=['sh.60', 'sz.00'], limitgt=0, start=0, end=0, withdata=True):\r\n",
      "    '''遍历证券信息，每个包含(Kdata, code, name)'''\r\n",
      "    conf = _config[frequency]\r\n",
      "    al = _all_stock(conf)\r\n",
      "    if limitgt > 0:\r\n",
      "        klen = 0\r\n",
      "    else:\r\n",
      "        limitgt = klen\r\n",
      "    count = 0\r\n",
      "    for i in al.index:\r\n",
      "        if end > 0 and count >= end:\r\n",
      "            break\r\n",
      "        c = al.loc[i]\r\n",
      "        if types and c.code[:5] not in types:\r\n",
      "            continue\r\n",
      "        if count < start:\r\n",
      "            continue\r\n",
      "        if withdata:\r\n",
      "            d = _kdata(c.code, klen, conf, False)\r\n",
      "            if len(d) > 0 and (limitgt == 0 or len(d) >= limitgt):\r\n",
      "                yield d, c.code, c.code_name\r\n",
      "        else:\r\n",
      "            yield None, c.code, c.code_name\r\n",
      "        count += 1\r\n",
      "\r\n",
      "def download(frequency='day'):\r\n",
      "    '''下载证券数据'''\r\n",
      "    print(dt.now(), '开始下载')\r\n",
      "    _download(_config[frequency])\r\n",
      "    print(dt.now(), '下载完成')\r\n",
      "\r\n",
      "def parse_args():\r\n",
      "    parser = argparse.ArgumentParser(\r\n",
      "        description='从baostock.com下载数')\r\n",
      "\r\n",
      "    parser.add_argument('--frequency', default='day', required=False,\r\n",
      "                        choices=['day', 'week'],\r\n",
      "                        help='选择下载日线还是周线，默认值：日线')\r\n",
      "\r\n",
      "    return parser.parse_args()\r\n",
      "\r\n",
      "if __name__ == '__main__':\r\n",
      "    args = parse_args()\r\n",
      "    download(args.frequency)\r\n"
     ]
    }
   ],
   "source": [
    "!cat /usr/local/lib/python3.8/dist-packages/localdata.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20e06fed",
   "metadata": {},
   "outputs": [],
   "source": [
    "#! /usr/bin/python\n",
    "# -*- coding: utf-8 -*-\n",
    "# @author HanYZ\n",
    "# @createAt 2022.07.17\n",
    "\n",
    "from os.path import expanduser, dirname, exists, getmtime, join\n",
    "from dateutil.relativedelta import relativedelta\n",
    "from datetime import datetime as dt\n",
    "from random import randint\n",
    "from os import makedirs\n",
    "import argparse\n",
    "import baostock as bs\n",
    "import pandas as pd\n",
    "import sys\n",
    "\n",
    "_datadir = join(expanduser('~'), '.local', 'datas')\n",
    "_sharedatadir = '/usr/local/share/datas' if sys.platform == 'linux' else _datadir\n",
    "\n",
    "_config = dict(\n",
    "    day = dict(\n",
    "        fields = \"date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,isST\",\n",
    "        filepath = lambda code: join(_datadir, 'day', code[:6], code+'.csv'),\n",
    "        sharefilepath = lambda code: join(_sharedatadir, 'day', code[:6], code+'.csv'),\n",
    "        listpath = join(_datadir, 'day', 'all_stock.csv'),\n",
    "        frequency = 'd',\n",
    "    ),\n",
    "    week = dict(\n",
    "        fields = \"date,code,open,high,low,close,volume,amount,adjustflag,turn,pctChg\",\n",
    "        filepath = lambda code: join(_datadir, 'week', code[:6], code+'.csv'),\n",
    "        sharefilepath = lambda code: join(_sharedatadir, 'week', code[:6], code+'.csv'),\n",
    "        listpath = join(_datadir, 'week', 'all_stock.csv'),\n",
    "        frequency = 'w',\n",
    "    )\n",
    ")\n",
    "\n",
    "def _lastDay(conf):\n",
    "    now = dt.now()\n",
    "    ld = now + relativedelta(hour=17, minute=35)\n",
    "    if ld > now:\n",
    "        ld += relativedelta(days=-1)\n",
    "    if ld.weekday() > 4 :\n",
    "        ld += relativedelta(days=4-ld.weekday())\n",
    "    elif ld.weekday() < 4 and conf['frequency'] == 'w':\n",
    "        ld += relativedelta(days=-3-ld.weekday())\n",
    "    return ld\n",
    "\n",
    "def _read_csv(filepath, klen):\n",
    "    data = pd.read_csv(filepath, index_col='date', parse_dates=True)\n",
    "    if klen > 0:\n",
    "        data = data.tail(klen)\n",
    "    return data\n",
    "\n",
    "def _to_csv(dataframe, filepath):\n",
    "    d = dirname(filepath)\n",
    "    if not exists(d):\n",
    "        makedirs(d)\n",
    "        print('创建', d)\n",
    "    dataframe.to_csv(filepath, index=0)\n",
    "\n",
    "def _downloadOne(code, conf, start_date='1991-01-01', write=True):\n",
    "    end_date = dt.now().date().isoformat()\n",
    "    rs = bs.query_history_k_data_plus(code, conf['fields'], start_date=start_date, end_date=end_date,\n",
    "                                      frequency=conf['frequency'], adjustflag='2').get_data()\n",
    "\n",
    "    # 写入文件\n",
    "    if len(rs) > 0:\n",
    "        write and _to_csv(rs, conf['filepath'](code))\n",
    "    else:\n",
    "        print('%s 的数据未读到' % code)\n",
    "    return rs\n",
    "\n",
    "def _refresh(code, conf, login=True):\n",
    "    filepath = conf['filepath'](code)\n",
    "    sharefilepath = conf['sharefilepath'](code)\n",
    "\n",
    "    if exists(sharefilepath) and dt.fromtimestamp(getmtime(sharefilepath)) > _lastDay(conf):  # 共享数据是新的\n",
    "        return False\n",
    "\n",
    "    if exists(filepath):  # 数据文件存在\n",
    "        if dt.fromtimestamp(getmtime(filepath)) > _lastDay(conf):  # 数据是新的\n",
    "            return False\n",
    "        if login:\n",
    "            bs.login()\n",
    "        old = _read_csv(filepath, klen=3)\n",
    "        if len(old) == 3:\n",
    "            last = old.index[0]\n",
    "            rs = _downloadOne(code, conf, start_date=last.date().isoformat(), write=False)\n",
    "            if len(rs) > 2 and old.open[2] == rs['open'].astype(float)[2]:  # 没有复权等情况影响历史数据\n",
    "                rs.loc[3:, :].to_csv(filepath, mode='a', index=False, header=None)\n",
    "                if login:\n",
    "                    bs.logout()\n",
    "                return True\n",
    "    elif login:\n",
    "        bs.login()\n",
    "\n",
    "    _downloadOne(code, conf)  # 重新下载\n",
    "    bs.logout\n",
    "    return True\n",
    "\n",
    "def _kdata(code, klen, conf, download=False):\n",
    "    filepath = conf['filepath'](code)\n",
    "    sharefilepath = conf['sharefilepath'](code)\n",
    "    if not exists(sharefilepath) and not exists(filepath):\n",
    "        download = True\n",
    "    download and _refresh(code, conf, True)\n",
    "    if exists(sharefilepath):\n",
    "        if exists(filepath) and getmtime(filepath) >= getmtime(sharefilepath):\n",
    "            return _read_csv(filepath, klen)\n",
    "        else:\n",
    "            return _read_csv(sharefilepath, klen)\n",
    "    else:\n",
    "        return _read_csv(filepath, klen)\n",
    "\n",
    "def _download(conf):\n",
    "    bs.login()\n",
    "    all_stock = bs.query_all_stock(_lastDay(conf).date().isoformat()).get_data()\n",
    "\n",
    "    cs = all_stock[~(all_stock.code.str.startswith('bj') | (all_stock.tradeStatus == '0') |\n",
    "                     all_stock.code_name.str.contains('退') | all_stock.code_name.str.contains('ST'))]\n",
    "    _to_csv(cs, conf['listpath'])\n",
    "\n",
    "    for i in cs.index:\n",
    "        c = cs.loc[i]\n",
    "        _refresh(cs.loc[i].code, conf, login=False)\n",
    "\n",
    "    bs.logout()\n",
    "    pass\n",
    "\n",
    "def _all_stock(conf):\n",
    "    filepath = conf['listpath']\n",
    "    if not exists(filepath):\n",
    "        _download(conf)\n",
    "    return pd.read_csv(filepath)\n",
    "\n",
    "def daily(code, klen=0, download=False):\n",
    "    return _kdata(code, klen, _config['day'], download)\n",
    "\n",
    "def weekly(code, klen=0, download=False):\n",
    "    return _kdata(code, klen, _config['week'], download)\n",
    "\n",
    "def anyone(frequency='day', klen=10):\n",
    "    '''任选一只证券，返回(Kdata, code, name)'''\n",
    "    conf = _config[frequency]\n",
    "    al = _all_stock(conf)\n",
    "    while True:\n",
    "        c = al.iloc[randint(0,len(al))]\n",
    "        d = _kdata(c.code, klen, conf, False)\n",
    "        if klen < 1 or len(d) >= klen:\n",
    "            return d, c.code, c.code_name\n",
    "\n",
    "def onebyone(frequency='day', klen=10, types=['sh.60', 'sz.00'], limitgt=0, start=0, end=0, withdata=True):\n",
    "    '''遍历证券信息，每个包含(Kdata, code, name)'''\n",
    "    conf = _config[frequency]\n",
    "    al = _all_stock(conf)\n",
    "    if limitgt > 0:\n",
    "        klen = 0\n",
    "    else:\n",
    "        limitgt = klen\n",
    "    count = 0\n",
    "    for i in al.index:\n",
    "        if end > 0 and count >= end:\n",
    "            break\n",
    "        c = al.loc[i]\n",
    "        if types and c.code[:5] not in types:\n",
    "            continue\n",
    "        if count < start:\n",
    "            continue\n",
    "        if withdata:\n",
    "            d = _kdata(c.code, klen, conf, False)\n",
    "            if len(d) > 0 and (limitgt == 0 or len(d) >= limitgt):\n",
    "                yield d, c.code, c.code_name\n",
    "        else:\n",
    "            yield None, c.code, c.code_name\n",
    "        count += 1\n",
    "\n",
    "def download(frequency='day'):\n",
    "    '''下载证券数据'''\n",
    "    print(dt.now(), '开始下载')\n",
    "    _download(_config[frequency])\n",
    "    print(dt.now(), '下载完成')\n",
    "\n",
    "def parse_args():\n",
    "    parser = argparse.ArgumentParser(\n",
    "        description='从baostock.com下载数')\n",
    "\n",
    "    parser.add_argument('--frequency', default='day', required=False,\n",
    "                        choices=['day', 'week'],\n",
    "                        help='选择下载日线还是周线，默认值：日线')\n",
    "\n",
    "    return parser.parse_args()\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    args = parse_args()\n",
    "    download(args.frequency)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
